home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / Mail / tty.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-08  |  5.2 KB  |  252 lines

  1. /*
  2.  * Copyright (c) 1980 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that the above copyright notice and this paragraph are
  7.  * duplicated in all such forms and that any documentation,
  8.  * advertising materials, and other materials related to such
  9.  * distribution and use acknowledge that the software was developed
  10.  * by the University of California, Berkeley.  The name of the
  11.  * University may not be used to endorse or promote products derived
  12.  * from this software without specific prior written permission.
  13.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  14.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  15.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  16.  */
  17.  
  18. #ifndef lint
  19. static char sccsid[] = "%W% (Berkeley) %G%";
  20. #endif /* not lint */
  21.  
  22. /*
  23.  * Mail -- a mail program
  24.  *
  25.  * Generally useful tty stuff.
  26.  */
  27.  
  28. #include "rcv.h"
  29.  
  30. static    int    c_erase;        /* Current erase char */
  31. static    int    c_kill;            /* Current kill char */
  32. static    jmp_buf    rewrite;        /* Place to go when continued */
  33. static    jmp_buf    intjmp;            /* Place to go when interrupted */
  34. #ifndef TIOCSTI
  35. static    int    ttyset;            /* We must now do erase/kill */
  36. #endif
  37.  
  38. /*
  39.  * Read all relevant header fields.
  40.  */
  41.  
  42. grabh(hp, gflags)
  43.     struct header *hp;
  44. {
  45.     struct sgttyb ttybuf;
  46.     int (*saveint)();
  47. #ifndef TIOCSTI
  48.     int (*savequit)();
  49. #endif
  50.     int (*savetstp)();
  51.     int (*savettou)();
  52.     int (*savettin)();
  53.     int errs;
  54.     int ttyint();
  55.  
  56.     savetstp = signal(SIGTSTP, SIG_DFL);
  57.     savettou = signal(SIGTTOU, SIG_DFL);
  58.     savettin = signal(SIGTTIN, SIG_DFL);
  59.     errs = 0;
  60. #ifndef TIOCSTI
  61.     ttyset = 0;
  62. #endif
  63.     if (gtty(fileno(stdin), &ttybuf) < 0) {
  64.         perror("gtty");
  65.         return(-1);
  66.     }
  67.     c_erase = ttybuf.sg_erase;
  68.     c_kill = ttybuf.sg_kill;
  69. #ifndef TIOCSTI
  70.     ttybuf.sg_erase = 0;
  71.     ttybuf.sg_kill = 0;
  72.     if ((saveint = signal(SIGINT, SIG_IGN)) == SIG_DFL)
  73.         signal(SIGINT, SIG_DFL);
  74.     if ((savequit = signal(SIGQUIT, SIG_IGN)) == SIG_DFL)
  75.         signal(SIGQUIT, SIG_DFL);
  76. #else
  77.     if (setjmp(intjmp))
  78.         goto out;
  79.     saveint = signal(SIGINT, ttyint);
  80. #endif
  81.     if (gflags & GTO) {
  82. #ifndef TIOCSTI
  83.         if (!ttyset && hp->h_to != NIL)
  84.             ttyset++, stty(fileno(stdin), &ttybuf);
  85. #endif
  86.         hp->h_to =
  87.             extract(readtty("To: ", detract(hp->h_to, 0)), GTO);
  88.     }
  89.     if (gflags & GSUBJECT) {
  90. #ifndef TIOCSTI
  91.         if (!ttyset && hp->h_subject != NOSTR)
  92.             ttyset++, stty(fileno(stdin), &ttybuf);
  93. #endif
  94.         hp->h_subject = readtty("Subject: ", hp->h_subject);
  95.     }
  96.     if (gflags & GCC) {
  97. #ifndef TIOCSTI
  98.         if (!ttyset && hp->h_cc != NIL)
  99.             ttyset++, stty(fileno(stdin), &ttybuf);
  100. #endif
  101.         hp->h_cc =
  102.             extract(readtty("Cc: ", detract(hp->h_cc, 0)), GCC);
  103.     }
  104.     if (gflags & GBCC) {
  105. #ifndef TIOCSTI
  106.         if (!ttyset && hp->h_bcc != NIL)
  107.             ttyset++, stty(fileno(stdin), &ttybuf);
  108. #endif
  109.         hp->h_bcc =
  110.             extract(readtty("Bcc: ", detract(hp->h_bcc, 0)), GBCC);
  111.     }
  112. out:
  113.     signal(SIGTSTP, savetstp);
  114.     signal(SIGTTOU, savettou);
  115.     signal(SIGTTIN, savettin);
  116. #ifndef TIOCSTI
  117.     ttybuf.sg_erase = c_erase;
  118.     ttybuf.sg_kill = c_kill;
  119.     if (ttyset)
  120.         stty(fileno(stdin), &ttybuf);
  121.     signal(SIGQUIT, savequit);
  122. #endif
  123.     signal(SIGINT, saveint);
  124.     return(errs);
  125. }
  126.  
  127. /*
  128.  * Read up a header from standard input.
  129.  * The source string has the preliminary contents to
  130.  * be read.
  131.  *
  132.  */
  133.  
  134. char *
  135. readtty(pr, src)
  136.     char pr[], src[];
  137. {
  138.     char ch, canonb[BUFSIZ];
  139.     int c;
  140.     register char *cp, *cp2;
  141.     int ttystop();
  142.  
  143.     fputs(pr, stdout);
  144.     fflush(stdout);
  145.     if (src != NOSTR && strlen(src) > BUFSIZ - 2) {
  146.         printf("too long to edit\n");
  147.         return(src);
  148.     }
  149. #ifndef TIOCSTI
  150.     if (src != NOSTR)
  151.         cp = copy(src, canonb);
  152.     else
  153.         cp = copy("", canonb);
  154.     fputs(canonb, stdout);
  155.     fflush(stdout);
  156. #else
  157.     cp = src == NOSTR ? "" : src;
  158.     while (c = *cp++) {
  159.         if (c == c_erase || c == c_kill) {
  160.             ch = '\\';
  161.             ioctl(0, TIOCSTI, &ch);
  162.         }
  163.         ch = c;
  164.         ioctl(0, TIOCSTI, &ch);
  165.     }
  166.     cp = canonb;
  167.     *cp = 0;
  168. #endif
  169.     cp2 = cp;
  170.     while (cp2 < canonb + BUFSIZ)
  171.         *cp2++ = 0;
  172.     cp2 = cp;
  173.     if (setjmp(rewrite))
  174.         goto redo;
  175.     signal(SIGTSTP, ttystop);
  176.     signal(SIGTTOU, ttystop);
  177.     signal(SIGTTIN, ttystop);
  178.     clearerr(stdin);
  179.     while (cp2 < canonb + BUFSIZ) {
  180.         c = getc(stdin);
  181.         if (c == EOF || c == '\n')
  182.             break;
  183.         *cp2++ = c;
  184.     }
  185.     *cp2 = 0;
  186.     signal(SIGTSTP, SIG_DFL);
  187.     signal(SIGTTOU, SIG_DFL);
  188.     signal(SIGTTIN, SIG_DFL);
  189.     if (c == EOF && ferror(stdin)) {
  190. redo:
  191.         cp = strlen(canonb) > 0 ? canonb : NOSTR;
  192.         clearerr(stdin);
  193.         return(readtty(pr, cp));
  194.     }
  195. #ifndef TIOCSTI
  196.     if (cp == NOSTR || *cp == '\0')
  197.         return(src);
  198.     cp2 = cp;
  199.     if (!ttyset)
  200.         return(strlen(canonb) > 0 ? savestr(canonb) : NOSTR);
  201.     while (*cp != '\0') {
  202.         c = *cp++;
  203.         if (c == c_erase) {
  204.             if (cp2 == canonb)
  205.                 continue;
  206.             if (cp2[-1] == '\\') {
  207.                 cp2[-1] = c;
  208.                 continue;
  209.             }
  210.             cp2--;
  211.             continue;
  212.         }
  213.         if (c == c_kill) {
  214.             if (cp2 == canonb)
  215.                 continue;
  216.             if (cp2[-1] == '\\') {
  217.                 cp2[-1] = c;
  218.                 continue;
  219.             }
  220.             cp2 = canonb;
  221.             continue;
  222.         }
  223.         *cp2++ = c;
  224.     }
  225.     *cp2 = '\0';
  226. #endif
  227.     if (equal("", canonb))
  228.         return(NOSTR);
  229.     return(savestr(canonb));
  230. }
  231.  
  232. /*
  233.  * Receipt continuation.
  234.  */
  235. ttystop(s)
  236. {
  237.     int (*old_action)() = signal(s, SIG_DFL);
  238.  
  239.     sigsetmask(sigblock(0) & ~sigmask(s));
  240.     kill(0, s);
  241.     sigblock(sigmask(s));
  242.     signal(s, old_action);
  243.     longjmp(rewrite, 1);
  244. }
  245.  
  246. /*ARGSUSED*/
  247. ttyint(s)
  248. {
  249.  
  250.     longjmp(intjmp, 1);
  251. }
  252.